﻿#if UNITY_EDITOR || UNITY_STANDALONE_WIN  //windows
#define ENABLE_CHECKING//发布时会关闭开关以提高性能
#endif

using UnityEngine;
using System.Collections.Generic;
#if ENABLE_CHECKING
using System;
using System.Diagnostics;
#endif

namespace TouchVoid.BuzzThree
{
    public interface IGlobalObject
    {
        /// <summary>
        /// Just trigger instantiation
        /// </summary>
        void Active();
        /// <summary>
        /// Release global object
        /// </summary>
        void Release();
    }

    /// <summary>
    /// 全局对象与Unity场景依赖相关的DontDestroyOnLoad需要统一管理，方便重启游戏时清除工作
    /// </summary>
    public class GlobalObjectManager
    {
        private static List<IGlobalObject> _globalObjects;
        private static List<GameObject> _gameObjects;

        public static void Retain(IGlobalObject go)
        {
            if (_globalObjects == null)
                _globalObjects = new List<IGlobalObject>();
            _globalObjects.Add(go);
        }

        public static void Retain(GameObject go)
        {
            UnityEngine.Object.DontDestroyOnLoad(go);
            if (_gameObjects == null)
                _gameObjects = new List<GameObject>();
            _gameObjects.Add(go);
        }

        public static void Release()
        {
            for(int i = 0; i < _globalObjects.Count; ++i)
                _globalObjects[i].Release();
            for (int i = 0; i < _gameObjects.Count; ++i)
                UnityEngine.Object.Destroy(_gameObjects[i]);
            _globalObjects.Clear();
            _gameObjects.Clear();
            Resources.UnloadUnusedAssets();
            //System.GC.Collect();
        }

        public static void ResourcesCleanUp()
        {
            Resources.UnloadUnusedAssets();
            //System.GC.Collect();
        }
    }

    /// <summary>
    /// all global object must inherit from this
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class GlobalObject<T> : IGlobalObject where T : GlobalObject<T>, new()
    {
        protected static T _instance = default(T);

        public static T Instance
        {
            get
            {
                if (null == _instance)
                {
                    _instance = new T();
                    _instance.Init();
                    GlobalObjectManager.Retain(_instance);
                }
                return _instance;
            }
        }

        protected GlobalObject()
        {
#if ENABLE_CHECKING//如果发布到手机平台这个开关会被关闭，所以检测只会在开发环境被调用
            var st = new StackTrace(9).ToString();
            var splitSign = new string[] { "\n" };
            var arr = st.Split(splitSign, StringSplitOptions.RemoveEmptyEntries);
            const string TARGET = "Culture=neutral, PublicKeyToken=null]].get_Instance()";
            if (arr.Length == 0 || arr[0].IndexOf(TARGET) < 0)
            {
                UnityEngine.Debug.Log(string.Format("请必须通过Instance方法来实例化{0}类", typeof(T).FullName));
            }
#endif//ENABLE_CHECKING
        }

        protected virtual void Init()
        {

        }

        public virtual void Active()
        {

        }

        public virtual void Release()
        {
            _instance = null;
        }
    }
}

